Files are one of the most important thing on any computer. Without them you could not store any data, or preferences. A computer would be useless without them. Folders are just important, allowing you to add structure to your hard disk. In VB, there are many functions which allow you to edit, create, rename and move files and folders, but the MSDN library does not do a very good job of explaining them. This tutorial intends to cover the basics of these functions, and will hopefully do better!.

The basic file operations in in VB are :

Name 
 Function 
 
FileCopy 
 Copies a file 
 
Kill 
 Deletes a file 
 
Name 
 Renames/moves a file 
 

To copy a file, you use the FileCopy function, which is very simple: 

FileCopy SourceFile, DestinationFile

So,

FileCopy "C:\test.txt", "C:\testdir\test2.txt"

copies text.txt to C:\testdir and renames it test2.txt

To delete a file, you use the Kill (!) function.

Kill FilePath

So,

Kill "C:\test folder\test.txt"

deletes text.txt from C:\test folder . This does not send it to the recycle bin! If you want to do this, click here.

To rename/move file:

Name OldNameandPath As NewNameandPath

So,

Name "C:\test.txt" As "C:\test2.txt"

Renames test.txt as test2.txt, and 

Name "C:\test.txt" As "C:\testdir\test2.txt"

moves text.txt to C:\testdir and renames is test2.txt You can also use this function to rename folders.

To see if a file exists, you can use the Dir function. If it returns nothing, then the file does not exist:

If Dir(FileName) = "" Then
    '// file does not exist
End If

However, this is not always reliable, especially on a network, and you should really use the WinApi method.

If you want to know how to do these operations using Win API, which allows you to send files to the recycle bin, and display the standard file copying dialog, click here.

There are also VB functions that allow you to rename, create and remove directories (called folders in Win 95/98). These are:

Name 
 Description 
 
MkDir 
 Creates a directory 
 
RmDir 
 Removes a directory 
 
Name 
 Renames a directory 
 

To create a directory, you use the MkDir function:

MkDir DirNameandPath

So,

MkDir "C:\testdir"

creates the directory testdir (so long as it does not already exist)

To remove a directory, you use the RmDir function:

RmDir DirNameandPath

So,

RmDir "C:\testdir"

removes the directory testdir (so long as it is empty)

To rename a directory, you use the Name Function:

Name OldNameandPath As NewNameandPath

So,

Name "C:\testdir" As "C:\testdir2"

Renames testdir as testdir2.

If you want to know how to do these operations using Win API, which allows you to send files to the recycle bin, and display the standard file copying dialog, click here.

Reading and writing files is one of the first things you will want to know how to do in Visual Basic, so here's how!

When you read and write files from Visual Basic, you always follow a number of steps:
1) Get a free file number using the FreeFile function. This is used to identify the file once you have opened the file.
2) Use the Open function to open the file for Input (read) or Output (write).
3) Perform an action on the file, either reading it or writing to it.
4) Close the file

To get a free file number, you use the FreeFile function:

' Get a free file number
nFileNum = FreeFile

Then, to open the file, we use the Open function. This takes the following syntax:

Open Filename For Method As FileNumber

Filename is the name of the file, Method is Input or Output (there are other methods, and these are discussed later), and FileNumber is a free file number. For example, the following code opens test.txt for Input:

' Get a free file number
nFileNum = FreeFile
' Open Test.txt for input. App.Path returns the path your app is saved in
Open App.Path & "c:\test.txt" For Input As nFileNum

If you aren't sure when to use Input and when to use Output, or, like me, can never remember which way round they go, take a look at the diagram below:

Next, we need to do something with it! To get some text from the file, we use the Input statement:

Input(Length, FileNumber)

So, if we wanted to load the first 100 characters from the file, we would use

Input(100, nFileNum)

where nFileNum is the file number we opened the file with.

You can then call the function again to read the next 100 characters and so on. If you want to move where you currently are in the file, use the Seek function:

Seek(FileNumber, Position)

For example, the following code loads the characters from 0 to 10, from 10 to 20, and then from 30 to 40:

sText = Input(10, nFileNum) 'first 10 chars
sText = sText & Input(10, nFileNum) 'next 10 chars
Seek nFileNum, 30 'go to char 30
sText = sText & Input(10, nFileNum) 'chars 30-40

If you want to get the whole file, you can use the LOF (Length of File) function. The following line returns the whole file:

Input(LOF(nFileNum), nFileNum)

If, on the other hand you want to write to the file, you use the Write function:

Write #nFileNum, Text

where, as usual nFileNum is the file number we opened the file with, and Text is the text we want to write to it. Please note that any text you write to the file will overwrite any existing text. If you don't want to do this, take a look at the Appending To Files section. Also note that each time you call the Write function, VB will automattically add a new line. So, if you write:

Write #nFileNum, "hello"
Write #nFileNum, "hello again" 

you will get

hello
hello again 

instead of

hellohello again

For those of you who are inquistive, and asking why we need the # before the file number, the answer is I don't know!

When you have finished with the file, you use the Close statement to close the file. VB does actually do this for you when your application closes, but it is a good habit to get into.

Close(nFileNum)

To put this all together, take a look at the following code. This reads the whole contents of Test.txt into TextBox1.

Dim nFileNum As Integer

' Get a free file number
nFileNum = FreeFile

' Open Test.txt for input. App.Path returns the path your app is saved in
Open App.Path & "Test.txt" For Input As nFileNum

' Read the contents of the file into TextBox1
TextBox1.Text = Input(LOF(nFilenum), nFileNum)

' Close the file
Close nFileNum

and, to write the contents of TextBox1 back to the file, you use the following code:

Dim nFileNum As Integer

' Get a free file number
nFileNum = FreeFile

' Create Test.txt 
Open App.Path & "c:\test.txt" For Output As nFileNum

' Write the contents of TextBox1 to Test.txt
Write #nFileNum, TextBox1.Text

' Close the file
Close nFileNum

Simple - Now, if you want to do some more advanced file reading/writing functions, go to the next page!

It is often useful to read a file line by line, especially if you need to parse the file if you have created your own special file format. Please note that this method is slower than reading the file all at once, so only use it if you really need to load the file line by line! 

Dim nFileNum As Integer, sText As String, sNextLine As String, lLineCount As Long

' Get a free file number
nFileNum = FreeFile

' Open Test.txt for input. App.Path returns the path your app is saved in
Open App.Path & "Test.txt" For Input As nFileNum
lLineCount = 1
' Read the contents of the file
Do While Not EOF(nFileNum)
    Line Input #nFileNum, sNextLine
    'do something with it
    'add line numbers to it, in this case!
    sNextLine = lLineCount & " " & sNextLine & vbCrLf
    sText = sText & sNextLine
    lLineCount = lLineCount + 1
Loop
TextBox1.Text = sText

' Close the file
Close nFileNum

Note that the Line Input function returns the current line to sNextLine. This does not include the new line character, so if you are displaying the text you need to add one!

When creating certain sorts of applications (e.g. Virus Scanner), you will want to be able to create a log of the scanners tasks. However if you used the previous example, you would overwrite the previous entry, as you entered the new one. This code opens test.txt and adds a entry to the end of a file

Dim nFileNum As Integer

' Get a free file number
nFileNum = FreeFile

' Open Test.txt for append
Open App.Path & "c:\test.txt" For Append As nFileNum

' Add the contents of TextBox1 to Test.txt
Print #nFileNum, TextBox1.Text

' Close the file
Close nFileNum

You might want, at some stage more control over what happens when opening a file. For example, you might want to prevent other applications from writing to it, while you were reading it, or prevent them from reading the file at all! This is all done using different options in the Open statement, and is actually quite simple. To use these, you simply use one of the following keywords after the As Input/Output part of the statement. For example,

Open File For Method LockOptions As nFileNum

The different lock options are explained below:

Shared Lets other applications (and the OS) do what it wants with the file, even if you are modifying it. 
Lock Read Prevents other applications from reading the file, until you close it. 
Lock Write Prevents other applications from writing to the file, until you close it. 
Lock Read Write Prevents other applications from writing to the file or reading it, until you close it. 

The last three options also prevent the open file from being deleted, and your program getting a nasty shock when it tries to write to/read from it again!

So,

Open App.Path & "\test.txt" For Input Lock Read Write As nFileNum

opens text.txt for Input, and prevents other applications from reading or writing to it, and stops it from being deleted.

Binary access is the most basic way to read a file. It is called binary access because you read the file byte by byte (letter by letter, character by character).

To open a file using Binary Access you simply say For Binary, instead of For Input or Output etc. So, 

Open App.Path & "c:\test.txt" For Binary As nFileNum

would open test.txt for binary access. To read characters from a file using binary access, you use the Get statement, which uses the following syntax:

Get FileNumber, ByteNumber, DestinationString

So, you pass the file number that you opened the file with, the byte to start at, and the string to put the result into. You will probably be wondering now how you specify how long a string to get. For binary access, you simply fill DestinationString with x number of spaces, where x is the number of characters you want to retrieve. For example, 

sMyString = Space(7)

Get #nFileNum, 12, sMyString 

would get 7 characters from the file (because sMyString is filled with 7 spaces), starting at byte 12 (the second parameter of Get). To write to a file using binary access, you use the Get statement:

Get FileNumber, ByteNumber, DestinationString

The following code opens a file for binary access and fills TextBox1 with bytes 12-18 of the file.

Dim nFileNum As Integer, sMyString As String 
' Get a free file number
nFileNum = FreeFile

' Open the file test.txt for binary access
Open "test.txt" For Binary As nFileNum

sMyString = Space(7)

' Read 7 characters from the file, starting at byte 12
Get #nFileNum, 12, sMyString

' Close the file
Close nFileNum

' Fill TextBox1 with the string
TextBox1.Text = sMyString

A Random Access file is like a database. It is made up of records of identical size. Each record is made up of fields that store data. You can use a Random Access file to store data from your application, like multiple addresses or Templates.

To use the following code, create 3 text boxes called txtAddress, txtName, txtPhone. Create a label called lblRecCount and 3 Command Button called cmdNext, cmdLast and cmdGotoRecord. Then enter the following code into your form code section. Take a look at the comments in the code to see how it all works.

' Add this to a module
Option Explicit
' Declare the record structure
Public Type PersonInfo
    Name As String * 40 ' Name String (40 character string)
    Phone As String * 40 ' Phone String (40 character string)
    Address As String * 50 ' Address String 50 character string)
End Type


'Add this to the form
Option Explicit
'The variable gPerson consists of the three variables contained in PersonInfo
Dim Person As PersonInfo
Dim lRecordLen As Long
Dim nFileNum As Integer
Dim lLastRecord As Long
Dim lCurrentRecord As Long
Private Sub Form_Load()
    ' Get the length of a record
    lRecordLen = Len(Person)
    ' Get a free file number
    nFileNum = FreeFile
    ' Open the file storing the information, if it does not exist create it
    Open App.Path & "Address.dat" For Random As nFileNum Len = lRecordLen
    ' Update the current record
    lCurrentRecord = 1
    ' Get the last record
    lLastRecord = FileLen(nFileNum)  / lRecordLen
    ' If the file has just been created update LastRecord
    If lLastRecord = 0 Then lLastRecord = 1
    ' Fill the textboxes with record1
    ShowCurrentRecord
End Sub
Private Sub Form_Unload(Cancel As Integer)
    ' Close the file
    Close nFileNum
End Sub
Sub ShowCurrentRecord()
    If lCurrentRecord = 0 Then lCurrentRecord = 1 
    ' This procedure fills the textboxes with the data
    Get #nFileNum, lCurrentRecord, Person
    ' Display the information
    txtName = Trim(Person.Name)
    txtAddress = Trim(Person.Address)
    txtPhone = Trim(Person.Phone)
    lblRecCount = "Record " & Str(lCurrentRecord)
End Sub

Sub SaveCurrentRecord()
    ' Fill gPerson from text boxes
    Person.Name = txtName
    Person.Phone = txtPhone
    Person.Address = txtAddress
    ' Save the data to the file
    Put #nFileNum, lCurrentRecord, Person
End Sub
Sub cmdGoToRecord_Click()
    Dim sResult As String
    ' Save the current record
    SaveCurrentRecord
    sResult = InputBox ("Enter the record number to go to")
    ' If cancel was pressed
    If sResult = "" Then
        Exit Sub
    ElseIf Not IsNumeric(sResult) Then
        ' A Number was not entered
        Msgbox "Please enter a number"
    Else
        lCurrentRecord = sResult
        ShowCurrentRecord
    End If
End Sub

Private Sub cmdNext_Click()
    ' Save the current record
    SaveCurrentRecord
    If lCurrentRecord = lLastRecord + 1 Then Exit Sub
    ' go next
    lCurrentRecord = lCurrentRecord + 1
    ShowCurrentRecord
End Sub
Private Sub cmdLast_Click()
    ' Save the current record
    SaveCurrentRecord
    If lCurrentRecord = 1 Then Exit Sub
    ' go next
    lCurrentRecord = lCurrentRecord - 1
    ShowCurrentRecord
End Sub

Before the occurrence of the registry in 32 bit Windows (Windows 95), if you wanted to save any form of application settings, such as the initial window size, you used INI files. Most applications store this information in the Windows registry now, however, you may find it easier to use INI files for now. One advantage of using INI files, is you can easily edit the files manually and also, any settings can easily be removed. INI files use the following structure:

[SectionName]
KeyName1 = KeyValue
KeyName2 = KeyValue

For an example of an INI files, look at the Win.ini file stored in your windows directory. The following code shows how to read and write to an INI file. Create a new project and go Projects | Add Module to add a new module.

Then add the following code. 

'// VB Web Code Example
'// www.vbweb.co.uk

' DLL declarations
Private Declare Function GetPrivateProfileString Lib "kernel32" Alias "GetPrivateProfileStringA" (ByVal lpApplicationName As String, ByVal lpKeyName As Any, ByVal lpDefault As String, ByVal lpReturnedString As String, ByVal nSize As Long, ByVal lpFileName As String) As Long
Private Declare Function WritePrivateProfileString Lib "kernel32" Alias "WritePrivateProfileStringA" (ByVal lpApplicationName As String, ByVal lpKeyName As Any, ByVal lpString As Any, ByVal lpFileName As String) As Long

'// Functions
Function GetFromINI(sSection As String, sKey As String, sDefault As String, sIniFile As String)
    Dim sBuffer As String, lRet As Long
    ' Fill String with 255 spaces
    sBuffer = String$(255, 0)
    ' Call DLL
    lRet = GetPrivateProfileString(sSection, sKey, "", sBuffer, Len(sBuffer), sIniFile)
    If lRet = 0 Then
        ' DLL failed, save default
        If sDefault <> "" Then AddToINI sSection, sKey, sDefault, sIniFile
        GetFromINI = sDefault
    Else
        ' DLL successful
        ' return string
        GetFromINI = Left(sBuffer, InStr(sBuffer, Chr(0)) - 1)
    End If
End Function

'// Returns True if successful. If section does not
'// exist it creates it.
Function AddToINI(sSection As String, sKey As String, sValue As String, sIniFile As String) As Boolean
    Dim lRet As Long
    ' Call DLL
    lRet = WritePrivateProfileString(sSection, sKey, sValue, sIniFile)
    AddToINI = (lRet)
End Function

You can then use this code to write and read from the ini files.